from enum import StrEnum,Enum

from sqlalchemy import func
from sqlalchemy.dialects.postgresql import JSONB
from models.engine import db
from models.online_mall.delivery import MUserOrderAddr
from models.online_mall.shop_msg import MShop
from models.types import StringUUID


class OrderPayType(Enum):
    MANUAL = 0
    WECHAT = 1
    ALIPAY = 2
    BANK = 3

class OrderStatus(StrEnum):
    WAIT_PAY = "P" # 待付款
    WAIT_DELIVER = "D" # 待发货
    WAIT_RECEIVE = "R" # 待收货
    WAIT_COMMENT = "C" # 待评价
    SUCCESS = "S" # 成功
    FAIL = "F" # 失败

class OrderDelStatus(StrEnum):
    NO_DEL = "N"
    RECOVERY = "R"
    DELETED = "F"

class OrderRefundStatus(StrEnum):
    NO_REFUND = "N"
    REFUNDING = "R"
    REFUNDED = "Y"

class OrderCloseType(StrEnum):
    NO_CLOSE = "N"
    TIMEOUT = "T"
    REFUND = "R"
    CANCEL = "C"
    CASH_ON_DELIVERY = "D" #货到付款

class RefundApplyType(Enum):
    REFUND = 1 #退款
    REFUND_RETURN = 2 #退款退货

class RefundReviewStatus(StrEnum):
    WAIT_REVIEW = "P"
    AGREE = "A"
    DIS_AGREE = "D"

class RefundStatus(StrEnum):
    PENDING = "P"
    SUCCESS = "S"
    FAILED = "F"
    
class MOrderItem(db.Model):
    __tablename__ = "sp_order_item"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="sp_order_item_pkey"),
        db.Index("sp_order_item_order_no_idx", "order_no"),
        db.Index("sp_order_item_prod_id_idx", "prod_id"),
    )
    id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
    order_no = db.Column(db.String(64), nullable=False,comment="订单编号")
    shop_id = db.Column(StringUUID, nullable=True,comment="店铺ID")
    prod_id = db.Column(StringUUID, nullable=False,comment="产品ID")
    sku_id = db.Column(StringUUID, nullable=False,comment="SKU ID")
    prod_count = db.Column(db.Integer, nullable=False,default=db.text('0'),comment="产品数量")
    prod_name = db.Column(db.String(128), nullable=False,comment="产品名称")
    sku_name = db.Column(db.String(128), nullable=False,comment="SKU名称")
    pic_file_id = db.Column(StringUUID, nullable=False,comment="产品主图片文件ID")
    price = db.Column(db.Integer, nullable=False,default=db.text('0'),comment="单价:分")
    account_id = db.Column(StringUUID, nullable=False,comment="账号ID")
    prod_total_amount = db.Column(db.Integer, nullable=False,default=db.text('0'),comment="产品总价:分")
    create_at = db.Column(db.TIMESTAMP, nullable=False,server_default=func.current_timestamp(),comment="创建时间")
    comment_status = db.Column(db.Boolean, nullable=False,server_default=db.text("false"),comment="是否评价")
    distribution_card_no = db.Column(db.String(36), nullable=True,comment="推广员使用的推销卡号")
    basket_time = db.Column(db.TIMESTAMP, nullable=True,comment="加入购物车时间:立即购买为空")
    # 检查 basket_date > rec_time 的异常数据（逻辑错误）。


class MOrder(db.Model):
    __tablename__ = "sp_order"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="sp_order_pkey"),
        db.Index("sp_order_account_id_idx", "account_id"),
        db.Index("sp_order_shop_id_idx", "shop_id"),
        db.Index("sp_order_order_no_idx", "order_no"),
    )
    id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
    tenant_id = db.Column(StringUUID, nullable=False,comment='租户ID')
    shop_id = db.Column(StringUUID, nullable=False)
    prod_names = db.Column(JSONB, nullable=True,server_default=db.text("'{}'::jsonb"),comment="产品名称:items")
    account_id = db.Column(StringUUID, nullable=False)
    order_no = db.Column(db.String(64), nullable=False,comment="订单编号")
    total = db.Column(db.Integer, nullable=False,default=db.text('0'),comment="订单表面总金额")
    actual_total = db.Column(db.Integer, nullable=False,default=db.text('0'),comment="订单实际总金额")
    pay_type = db.Column(db.SmallInteger, nullable=True,comment="支付类型:0:手动代付，1：微信，2：支付宝")
    remarks = db.Column(db.String(1024), nullable=True,comment="订单备注")
    status = db.Column(db.String(1),nullable=True,server_default=db.text("'P'"), comment="订单状态:P:待付款，D：待发货，R：待收货，C：待评价，S：成功，F：失败")
    dvy_type = db.Column(db.String(10), nullable=True,comment="配送类型")
    dvy_id = db.Column(StringUUID, nullable=True,comment="配送公司ID")
    dvy_flow_id = db.Column(db.String(128), nullable=True,comment="配送公司流水号")
    freight_amount = db.Column(db.Integer, nullable=True,default=db.text('0'),comment="运费金额:分")
    addr_order_id = db.Column(db.BigInteger, nullable=True,comment="用户收货地址ID")
    prod_nums = db.Column(db.Integer, nullable=True,default=db.text('0'),comment="商品数量")
    create_at = db.Column(db.TIMESTAMP, nullable=False,server_default=func.current_timestamp(),comment="创建时间")
    updated_at = db.Column(db.TIMESTAMP, nullable=True,comment="更新时间")
    pay_at = db.Column(db.TIMESTAMP, nullable=True,comment="支付时间")
    dvy_at = db.Column(db.TIMESTAMP, nullable=True,comment="配送时间")
    finally_at = db.Column(db.TIMESTAMP, nullable=True,comment="完成时间")
    cancel_at = db.Column(db.TIMESTAMP, nullable=True,comment="取消时间")
    is_payed = db.Column(db.Boolean, nullable=True,server_default=db.text("false"),comment="是否支付")
    del_status = db.Column(db.String(1), nullable=True,server_default=db.text("'N'"),comment="删除状态:N:未删除，R：回收站F:永久删除")
    refund_status = db.Column(db.String(1), nullable=True,server_default=db.text("'N'"),comment="退款状态:N:未退款，R:退款中,Y:已退款")
    reduce_amount = db.Column(db.Integer, nullable=True,default=db.text('0'),comment="优惠金额:分")
    order_type = db.Column(db.SmallInteger, nullable=True,server_default=db.text('0'),comment="订单类型:0:普通订单，1：秒杀订单")
    close_type = db.Column(db.String(1), nullable=True,server_default=db.text("'N'"),comment="订单关闭类型:N:未关闭，T:超时关闭，R:退款，C:取消,D:货到付款")

    @property
    def ShopName(self)->str|None:
        if self.shop_id:
            return db.session.query(MShop.name).filter(MShop.id==self.shop_id).scalar()
        return None
    @property
    def ProductNames(self)->list[str]:
        if self.prod_names:
            return self.prod_names.get("items",[])
        return []
    
    @ProductNames.setter
    def ProductNames(self,value:list[str]):
        if self.prod_names:
            self.prod_names["items"] = value
        else:
            self.prod_names = {"items":value}

    @property
    def Total(self)->float|None:
        if self.total:
            return self.total*(1/1000)
        return None
    
    @Total.setter
    def Total(self,value:float):
        self.total = int(value*1000)

    @property
    def ActualTotal(self)->float|None:
        if self.actual_total:
            return self.actual_total*(1/1000)
        return None
    
    @ActualTotal.setter
    def ActualTotal(self,value:float):
        self.actual_total = int(value*1000)

    @property
    def FreightAmount(self)->float|None:
        if self.freight_amount:
            return self.freight_amount*(1/1000)
        return None
    
    @FreightAmount.setter
    def FreightAmount(self,value:float):
        self.freight_amount = int(value*1000)

    @property
    def items(self)->list[MOrderItem]:
        return db.session.query(MOrderItem).filter(MOrderItem.order_no==self.order_no).all()
    
    @property
    def user_addr_order(self)->MUserOrderAddr|None:
        if self.addr_order_id:
            return db.session.get(MUserOrderAddr,self.addr_order_id)
        return None


class MOrderSettlement(db.Model):
    __tablename__ = "sp_order_settlement"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="sp_order_settlement_pkey"),
        db.Index("sp_order_settlement_order_no_idx", "order_no"),
        db.Index("sp_order_settlement_account_id_idx", "account_id"),
    )
    id = db.Column(db.BigInteger, primary_key=True, autoincrement=True,comment="ID")
    pay_no = db.Column(db.String(32), nullable=False,comment="支付单号")
    biz_pay_no = db.Column(db.String(255), nullable=True,comment="外部支付流水号")
    order_no = db.Column(db.String(64), nullable=False,comment="订单编号")
    pay_type = db.Column(db.SmallInteger, nullable=False,comment="支付类型:0:手动代付，1：微信，2：支付宝")
    pay_type_name = db.Column(db.String(64), nullable=True,comment="支付方式名称")
    pay_amount = db.Column(db.Integer, nullable=False,default=db.text('0'),comment="支付金额:分")
    is_clearing = db.Column(db.Boolean, nullable=False,server_default=db.text("false"),comment="是否结算/清算")
    account_id = db.Column(StringUUID, nullable=False,comment="账号ID")
    create_at = db.Column(db.TIMESTAMP, nullable=False,server_default=func.current_timestamp(),comment="创建时间")
    ver = db.Column(db.Integer, nullable=False,server_default=db.text('0'),comment="版本号")
    pay_status = db.Column(db.Boolean, nullable=False,server_default=db.text("false"),comment="支付状态")

class MOrderRefund(db.Model):
    __tablename__ = "sp_order_refund"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="sp_order_refund_pkey"),
        db.Index("sp_order_refund_order_no_idx", "order_no"),
        db.Index("sp_order_refund_refund_sn_idx", "refund_sn"),
    )
    id = db.Column(db.BigInteger, primary_key=True, autoincrement=True,comment="ID")
    shop_id = db.Column(StringUUID, nullable=True,comment="店铺ID")
    order_id = db.Column(db.BigInteger, nullable=False,comment="订单ID")
    order_no = db.Column(db.String(64), nullable=False,comment="订单编号")
    order_amount = db.Column(db.Integer, nullable=False,default=db.text('0'),comment="订单金额:分")
    order_item_id = db.Column(db.BigInteger, nullable=True,comment="订单项ID:空时为整单退")
    refund_sn = db.Column(db.String(64), nullable=False,comment="退款单号")
    flow_trade_no = db.Column(db.String(32), nullable=True,comment="订单支付流水号")
    out_refund_no = db.Column(db.String(255), nullable=True,comment="第三方退款单号(微信退款单号)")
    pay_type = db.Column(db.SmallInteger, nullable=False,comment="支付类型:0:手动代付，1：微信，2：支付宝")
    pay_type_name = db.Column(db.String(64), nullable=True,comment="支付方式名称")
    account_id = db.Column(StringUUID, nullable=False,comment="账号ID")
    goods_num = db.Column(db.Integer, nullable=False,default=db.text('0'),comment="退货数量")
    refund_amount = db.Column(db.Integer, nullable=False,default=db.text('0'),comment="退款金额:分")
    apply_type = db.Column(db.SmallInteger, nullable=False,comment="申请类型:1:仅退款，2：退货退款")
    review_status = db.Column(db.String(1),nullable=False,default=db.text("P"),comment="审核状态:P:待审核，A:同意，D:不同意")
    refund_status = db.Column(db.String(1), nullable=False,default=db.text("N"),comment="处理退款状态: N:退款处理中 S:退款成功 F:退款失败")
    apply_at = db.Column(db.TIMESTAMP,nullable=False,server_default=func.current_timestamp(),comment="申请时间")
    handel_at = db.Column(db.TIMESTAMP,nullable=True,comment="卖家处理时间")
    refund_at = db.Column(db.TIMESTAMP,nullable=True,comment="退款时间")
    photo_files = db.Column(JSONB,server_default=db.text("'{}'::jsonb"),comment="文件凭证列表:items")
    buyer_msg = db.Column(db.String(300),nullable=True,comment="申请退款原因")
    seller_msg = db.Column(db.String(300),nullable=True,comment="卖家备注")
    express_name = db.Column(db.String(128),nullable=True,comment="物流公司名称")
    express_no =  db.Column(db.String(64),nullable=True,comment="物流单号")
    ship_at = db.Column(db.TIMESTAMP,nullable=True,comment="发货时间")
    receive_at = db.Column(db.TIMESTAMP,nullable=True,comment="收货时间")
    receive_msg = db.Column(db.String(300),nullable=True,comment="收获备注")



